\chapter{关于本书}
C++17是现代C++编程中的下一个版本，最新版本的gcc、clang和Visual C++都至少已经部分支持它。
尽管迁移到C++17并不像迁移到C++11一样是一个巨大的变化，但C++17也包含了非常多很小但却很有价值的语言和库特性。
它们再一次改变了我们使用C++编程的方式，无论是对应用程序员还是提供基础库的程序员来说都是如此。

这本书将会展现出C++17中所有的新的语言和库特性。
除了用例子展示这些特性的使用之外，本书还将覆盖这些特性的动机和背景信息。
像我的其他书一样，这本书也将专注于这些新特性在实践中的应用，
并演示这些特性如何影响我们的日常编程和如何在项目中受益于这些特性。

\section{阅读前须知}\label{须知}
为了尽可能的从这本书中获益，你应该已经对C++非常熟悉，最好是熟悉C++11和/或C++14。
然而，你不需要是专家。
我的目标是让本书的内容能被平均水平的C++程序员理解，不需要知道所有最新特性的细节。
你应该熟悉类和继承的概念、能使用C++标准库里的一些组件例如IOstream和容器来编写C++程序。
你还应该熟悉“现代C++”的基本特性，例如\texttt{auto}、\texttt{decltype}、move语义和lambda。

我将讨论基本的特性并在需要时审查一些细微的问题，即使这些问题并不直接和C++17相关。
这样能确保本书对专家和中级程序员也有一些作用。

注意我通常会使用花括号这种现代的初始化方式（C++11引入的\emph{统一初始化(uniform initialization)}）：
\begin{lstlisting}
    int i{42};
    std::string s{"hello"};
\end{lstlisting}
这种被称为\emph{列表初始化(list initialization)}的初始化方式有一个优势是
可以用于基础类型、类类型、聚合体类型（\hyperref[ch4]{C++17中进行了扩展}）、
枚举类型（\hyperref[ch8.3]{C++17中添加了相应的新特性}）和\texttt{auto}，
还可以检测到窄化（例如，用一个浮点值初始化一个\texttt{int}）。
如果花括号为空，那么将调用每个（子）对象的默认构造函数，基础类型会被初始化为
\texttt{0/false/nullptr}。\footnote{唯一的例外是原子类型（类型\texttt{std::atomic<>}），
即使是列表初始化也不能保证正确的初始化它们。这个问题在C++20中有希望修复。}

\section{本书的整体结构}
这本书覆盖了C++17引入的\emph{所有}变化。
既包括影响应用程序员日常编程的那些语言和库特性，
也包括那些用于编写复杂的（基础）库实现的特性。
然而，更一般的情况和相关示例会放在前面。

不同的章节被分成若干组，除了最先介绍的语言特性可能会被后面的库特性使用之外，
这样分组并没有什么深层的原因。
理论上，你可以以任意顺序阅读这些章节。
如果会用到其他章节的特性，那么将会有相应的交叉引用。

结果是，这本书包括以下部分：
\begin{itemize}
    \item \textbf{Part \uppercase\expandafter{\romannumeral 1}}覆盖了新的非模板语言特性。
    \item \textbf{Part \uppercase\expandafter{\romannumeral 2}}覆盖了用于模板泛型编程的新的语言特性。
    \item \textbf{Part \uppercase\expandafter{\romannumeral 3}}介绍了新的标准库组件。
    \item \textbf{Part \uppercase\expandafter{\romannumeral 4}}覆盖了现有标准库组件的扩展和修改。
    \item \textbf{Part \uppercase\expandafter{\romannumeral 5}}覆盖了为专家例如基础库程序员设计的语言和库特性。
    \item \textbf{Part \uppercase\expandafter{\romannumeral 6}}包含了有关C++17的一些通用的提示。
\end{itemize}

\section{如何阅读本书}
根据我的经验，学习一个新东西的最佳方法是阅读示例。因此，你可以在这本书中找到很多示例。
有些只是用来说明一个抽象概念的几行代码，有些是提供了具体应用的完整程序。
后者将会有一个注释来说明包含有源码的文件名。
你可以在这本书的网站\url{http://www.cppstd17.com}中找到这些源码文件。

\section{错误术语}
注意我经常讨论程序错误。
如果没有特殊的提示，术语\emph{错误(error)}或者一个类似于
\begin{lstlisting}
    ... // ERROR
\end{lstlisting}
的注释意味着这是一个编译期错误。
相应的代码不能通过编译（在使用一个符合标准的编译器的情况下）。

如果我使用术语\emph{运行时错误(runtime error)}，那么程序可以编译但不能正确工作
或者会导致未定义行为（也就是说，它可能会也可能不会有预期行为）。

\section{C++17标准}
最初的C++标准发布于1998年，之后在2003年由一份\emph{技术勘误(technical corrigendum)}进行修正，
里面提供了很多对最初标准的微小修正和说明。这个“旧C++标准”被称为C++98或者C++03。

“现代C++”的世界开始于C++11，在C++14中进行了扩展。
国际C++标准委员会现在致力于每三年提出一个新标准。
这样做会导致添加特性的时间变少，但能更快速的把变化带给广大的编程社区。
因此，大型特性的添加需要消耗更多的时间，甚至可能会横跨多个标准。

C++17只是下一个标准，并不是革命性的标准，但它带来了非常多的改进和扩展。

当编写这本书时，C++17已经被主流编译器至少部分支持。
然而，像通常一样，这些编译器在对新语言特性的支持上有很大不同。
有一些可以编译本书中大多数甚至是全部的代码，而另外一些可能只能处理一个子集。
然而，我希望这个问题可以早点解决，因为世界各处的程序员们需要他们的编译期供应商对标准的支持。

\section{示例代码和附加信息}
你可以在本书的网站中找到所有的示例代码和有关本书的更多信息，网址是：\\
\hspace*{2em}\url{http://www.cppstd17.com}

\section{反馈}
我非常欢迎你们的有建设性的意见——不管是负面的还是正面的。
我非常努力地工作希望能带给你想要的东西来让本书成为一本优秀的书籍。
然而，有时我不得不停止书写，然后进行审阅和调整来“发布新版本”。
你们可能会发现错误、不一致、还可以改进的内容、或者完全丢失的话题。
你们的反馈将给我一个机会来修复这些错误，然后在这本书的网站上通知所有读者这个修正，
并改进以后的任何修订或新版本。

联系我的最佳方式是电子邮件。你可以在这本书的网站：\\
\hspace*{2em}\url{http://www.cppstd17.com}\\
上找到我的电子邮件地址。

请确保你有这本书的最新版本（记住它是以增量方式编写和发布的）并在反馈时给出该版本的发布日期。
当前的发布日期是\textbf{2019-12-20}。

非常感谢。
